import tkinter as tk
from page import StartPage
from tkinter import filedialog, messagebox
import os
import shutil
from pathlib import Path
from page.Config import Config
from PIL import ImageTk, Image
from page.UsePage import UsePage
import logging
from datetime import datetime

class SetPage(tk.Frame):

    winWidth = 800
    winHeight = 400
    bgSrc = "resource/bg/bg.png"

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        # 设置背景图片
        bg_img = ImageTk.PhotoImage(UsePage.show_image_with_size(UsePage,rf"{Config.resource_path(self.bgSrc)}"))
        # 在Frame中创建Label作为背景
        self.bg_canvas = tk.Canvas(self, width=self.winWidth, height=self.winHeight,bg="white", highlightthickness=0)
        self.bg_canvas.place(x=0, y=0, relwidth=1, relheight=1)
        self.bg_canvas.create_image(
            0, 0,
            image=bg_img,
            anchor='nw',
            tags="bg"
        )
        self.bg_canvas.bg = bg_img

        # 设置背景色
        self.configure(bg="#FFA500")

        # 设置grid布局 4x4
        for row in range(12):
            self.rowconfigure(row, weight=1)
        for col in range(12):        
            self.columnconfigure(col, weight=1)   

        # 创建界面组件
        # 公司名称
        tk.Label(self,text="公司名称：").grid(row=0,column=0)
        self.company_entry = tk.Entry(self,width=40)
        self.company_entry.grid(row=0,column=1)

        # 抽奖标题
        tk.Label(self,text="抽奖标题：").grid(row=1,column=0)
        self.title_entry = tk.Entry(self,width=40)
        self.title_entry.grid(row=1,column=1)
        
        # 设置账号
        tk.Label(self,text="账号：").grid(row=2,column=0)
        self.username_entry = tk.Entry(self,width=40)
        self.username_entry.grid(row=2,column=1)

        # 设置密码
        tk.Label(self,text="密码：").grid(row=3,column=0)
        self.password_entry = tk.Entry(self,width=40, show="*")
        self.password_entry.grid(row=3,column=1)

        # 背景图片
        tk.Label(self, text="背景图片:").grid(row=4, column=0)
        self.bg_entry = tk.Entry(self, width=40)
        self.bg_entry.grid(row=4, column=1)
        tk.Button(self, text="选择", command=self.upload_backgroud).grid(row=4, column=2)

        # 上传背景音乐
        tk.Label(self,text="背景音乐:").grid(row=5,column=0)
        self.music_entry = tk.Entry(self,width=40)
        self.music_entry.grid(row=5,column=1)
        tk.Button(self,text="选择",command=self.upload_music).grid(row=5,column=2)

        # 上传抽奖名单
        tk.Label(self,text="抽奖名单:").grid(row=6,column=0)
        self.userlist_entry = tk.Entry(self,width=40)
        self.userlist_entry.grid(row=6,column=1)
        tk.Button(self,text="选择",command=self.upload_userlist).grid(row=6,column=2)

        # 上传奖品名单
        tk.Label(self,text="奖品列表:").grid(row=7,column=0)
        self.awardlist_entry = tk.Entry(self,width=40)
        self.awardlist_entry.grid(row=7,column=1)
        tk.Button(self,text="选择",command=self.upload_awardlist).grid(row=7,column=2)

        #返回和保存按钮
        btn1 = tk.Button(self, text="返回",command=lambda: controller.show_frame(StartPage.StartPage))
        btn1.grid(row=9,column=9)
        btn1 = tk.Button(self, text="保存",bg="#4CAF50",fg="white",command=self.saveData)
        btn1.grid(row=9,column=10)
        btn1 = tk.Button(self, text="导出中奖名单",bg="#0000FF",fg="white",command=self.export)
        btn1.grid(row=9,column=11)

    # 上传背景图片
    def upload_backgroud(self):
        filetypes = (
            ('JPEG 图片', '*.jpeg;*.jpg'),
            ('PNG 图片', '*.png'),
            ('GIF 图片', '*.gif'),
            ('BMP 图片', '*.bmp'),
            ('所有文件', '*.*')
        )

        if path := filedialog.askopenfilename(title="选择图片文件",filetypes=filetypes):
            self.bg_entry.delete(0, tk.END)
            self.bg_entry.insert(0, path)

        if path:
            if not path.lower().endswith(('.png', '.jpg', '.jpeg', '.gif', '.bmp')):
                messagebox.showerror("错误", "请选择有效的图片格式！")
                return

    # 上传音乐
    def upload_music(self):
        filetypes = [
            ('MP3 音乐', '*.mp3'),
            ('WAV 音乐', '*.wav'),
            ('AAC 音乐', '*.aac'),
            ('FLAC 音乐', '*.flac'),
            ('所有文件', '*.*')
        ]
        
        if filepath := filedialog.askopenfilename(title="选择音乐文件",filetypes=filetypes):
            self.music_entry.delete(0, tk.END)
            self.music_entry.insert(0, filepath)
        
        if filepath:
            if not filepath.lower().endswith(('.mp3', '.wav', '.aac', '.flac')):
                messagebox.showerror("错误", "请选择有效的音乐格式！")
                return

    # 上传抽奖名单
    def upload_userlist(self):
        filetypes = [
            ('Excel文件', '*.xlsx;*.xls'),
            ('所有文件', '*.*')
        ]
        
        if filepath := filedialog.askopenfilename(title="选择Excel文件",filetypes=filetypes):
            self.userlist_entry.delete(0, tk.END)
            self.userlist_entry.insert(0, filepath)
        
        if filepath:
            if not filepath.lower().endswith(('.xlsx', '.xls')):
                messagebox.showerror("错误", "请选择有效的Excel格式！")
                return

    # 上传奖品名单
    def upload_awardlist(self):
        filetypes = [
            ('Excel文件', '*.xlsx;*.xls'),
            ('所有文件', '*.*')
        ]
        
        if filepath := filedialog.askopenfilename(title="选择Excel文件",filetypes=filetypes):
            self.awardlist_entry.delete(0, tk.END)
            self.awardlist_entry.insert(0, filepath)
        
        if filepath:
            if not filepath.lower().endswith(('.xlsx', '.xls')):
                messagebox.showerror("错误", "请选择有效的Excel格式！")
                return        

    # 文件转存       返回 绝对地址以及相对地址 
    def transfer_file(self,source: str, destination_dir: str) -> str:
        """将文件转存到目标目录，返回新路径"""
        try:
            source_path = Path(source)
            if not source_path.exists():
                raise FileNotFoundError(f"源文件不存在: {source}")
            
            dest_dir = Config.resource_path(destination_dir)
            dest_dir.mkdir(parents=True, exist_ok=True)
            dest_path = os.path.join(dest_dir , source_path.name)
            os.makedirs(dest_dir, exist_ok=True)
            shutil.copy2(str(source_path), str(dest_path))

            return str(dest_path),str(os.path.join(f"{os.path.normpath(destination_dir)}" , source_path.name))
        except PermissionError:
            messagebox.showerror("错误", "权限不足，请检查目标路径或使用管理员权限运行")
        except Exception as e:
            messagebox.showerror("错误", f"转存失败:{e}")
            return None

    # 初始化
    def initData(self):
        config = Config()
        self.company_entry.delete(0, tk.END)
        self.company_entry.insert(0, config.data['company'])
        self.title_entry.delete(0, tk.END)
        self.title_entry.insert(0, config.data['title'])
        self.username_entry.delete(0, tk.END)
        self.username_entry.insert(0, config.data['username'])
        self.password_entry.delete(0, tk.END)
        self.password_entry.insert(0, config.data['password'])
        self.bg_entry.delete(0, tk.END)
        self.bg_entry.insert(0, config.data['backgroud'])
        self.music_entry.delete(0, tk.END)
        self.music_entry.insert(0, config.data['music'])
        self.userlist_entry.delete(0, tk.END)
        self.userlist_entry.insert(0, config.data['userlist'])
        self.awardlist_entry.delete(0, tk.END)
        self.awardlist_entry.insert(0, config.data['awardlist'])

    # 保存
    def saveData(self):
        data = {
            "company":self.company_entry.get(),
            "title":self.title_entry.get(),
            "username":self.username_entry.get(),
            "password":self.password_entry.get(),
            "backgroud":self.bg_entry.get(),
            "music":self.music_entry.get(),
            "userlist":self.userlist_entry.get(),
            "awardlist":self.awardlist_entry.get(),
        }

        fieldcheck = {
            "company":"公司名不能为空",
            "title":"标题不能为空",
            "username":"用户名不能为空",
            "password":"密码不能为空",
            "backgroud":"背景图片不能为空",
            "music":"音乐不能为空",
            "userlist":"抽奖名单不能为空",
            "awardlist":"奖品名单不能为空",
        }

        # 验证是否有空
        for key in fieldcheck:
            if data[key] is not None and data[key] != "":
                continue
            else:
                messagebox.showerror("提示", fieldcheck[key])
                return
                
        config = Config()

        # 文件转存
        SetPage.setup_logger()
        try:
            if data['backgroud'] != config.data['backgroud']:
                data['backgroud'],data['backgroudSrc'] = self.transfer_file(data['backgroud'],"resource/bg/")
            if data['music'] != config.data['music']:    
                data['music'],data['musicSrc'] = self.transfer_file(data['music'],"resource/music/")
            if data['userlist'] != config.data['userlist']:  
                data['userlist'],data['userlistSrc'] = self.transfer_file(data['userlist'],"resource/excel/")
                Config.toExcel(data['userlist'],'userlist')
            if data['awardlist'] != config.data['awardlist']:      
                data['awardlist'],data['awardlistSrc'] = self.transfer_file(data['awardlist'],"resource/excel/")
                Config.toExcel(data['awardlist'],'awardlist')
        except Exception as e:
            logging.error(f"发生异常: {type(e).__name__}", exc_info=True)
            print(f"错误已记录到log.txt (错误类型: {type(e).__name__})")
        config.data.update(data)
        config.dump()
        self.initData()

        messagebox.showinfo("提示","保存成功！")

    # 导出中奖名单
    def export(self):
        data = Config.toJson('./data/winlist.json')
        if data:
            Config.exportWinList()
            messagebox.showinfo("提示","已导出在根目录下")
            pass
        else:
            messagebox.showerror("错误","当前并没有中奖名单！")
        pass

    # 进入页面
    def on_enter(self):
        self.initData()
        pass
    
    # 离开页面
    def on_leave(self):
        pass

    # 捕获报错
    def setup_logger():
        logging.basicConfig(
            filename='log.txt',
            level=logging.ERROR,
            format='%(asctime)s - %(levelname)s - %(message)s'
        )
        pass